<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            margin-bottom: 1000px;
        }
        .box{
            border: 3px dashed #ccc;
            padding: 20px;
        }
    </style>
    <script src="../assets/js/vue.js"></script>
</head>
<body>
    <div id="app" class="box">
        <!--
        + 技术实现：事件绑定，事件触发  (1.如何让子组件调用父组件的相关功能;2.被动的触发子组件向父组件进行数据发送)
        + 详细描述
                事件绑定 : 通过v-on完成自定义事件的绑定，将父组件方法提供给子组件事件仓库($listeners)作为回调函数
                          => vue在解析子组件时，以v-on绑定的任何名称均为 自定义事件名
                事件触发 : 在子组件中通过 $listeners 调用对应的 自定义事件方法名，并使用子组件的变量作为参数进行方法调用，
                        此时父组件提供的回调方法将接受到来自子组件的参数，但开发时建议使用 $emit 替代 $listeners，因为
                        $emit 可以在调试工具中记录日志
        -->
        <p>父组件</p>
        <p>msg:{{ msg }}</p>
        <!-- vue内逻辑代码的定义规则，导致在组件绑定的事件，如果定义(),将无法接受到来自于子组件的传入数据 -->
        <!-- <comp-a :aa=" fun " v-on:click=" setMsg() "></comp-a> -->
        <comp-a :aa=" fun " v-on:click=" setMsg "></comp-a>

    </div>


    <script type="text/x-template" id="compA">
        <div class="box">
            <p>子组件</p>
            <p>msg:{{ msg }}</p>
            <input type="button" value="更新msg" @click="upadteMsg()">
        </div>
    </script>

    <script>
        Vue.component("CompA", {
            template:"#compA",
            data() {
                return {
                    msg:"子组件数据变量msg"
                }
            },
            props:{
                aa:Function
            },
            methods:{
                upadteMsg(){
                    this.msg = "子组件重新赋值"
                    this.$emit("click",this.msg)
                    // this.$listeners.click(this.msg)
                }
            },
            created() {
                this.aa(this.msg);
                console.log("事件仓库:",this.$listeners)
                // this.$listeners.click(this.msg)
                // 在子组件中，vue官方提供 $emit 实例方法，用于替代上述 的 $listeners 的调用
                // vm.$emit("自定义事件名",携带的方法参数)
                // 使用$emit 可以在开发工具中产生记录日志
                this.$emit("click",this.msg)
            },
        })

        new Vue({
            el:"#app",
            data:{
                msg:"",
                fun:function(nv){
                    console.log("父组件传递给子组件的方法:来自于子组件的数据:",nv)
                    // data仓库中的方法只是作为变量存在，不会被vue进行this锁定操作，
                    // 所以该部分的this按照普通方法的this进行识别,this指向于调用者对象
                    this.msg = nv;
                    console.log(this)
                }
            },
            methods: {
                setMsg(nv){
                    console.log("父组件传递给子组件的方法:来自于子组件的数据:",nv)
                    console.log(this)
                    this.msg = nv;
                }
            },
        })
    </script>
</body>
</html>